package com.authine.cloudpivot.ext.applicationservice;

import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.constants.ServiceUrlConst;
import com.authine.cloudpivot.ext.domain.dto.ApprovalFlowStrategyDto;
import com.authine.cloudpivot.ext.domain.dto.StartWorkFlowDto;
import com.authine.cloudpivot.ext.dto.BatchSubmitDto;
import com.authine.cloudpivot.ext.utils.HttpClients;
import com.authine.cloudpivot.ext.utils.boQuery.BoQueryUtils;
import com.authine.hermes.app.flow.runtime.dto.clientobject.HandleWorkItemValidMessageVO;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

@Path("ApprovalFlowStrategyService")
@Slf4j
@Primary
public class ApprovalFlowStrategyService extends ApplicationService {

    private static final NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);


    @Path("queryParticipantHttpClient")
    @POST
    @Operation(summary = "流程审批管理-获取节点参与者", tags = CUSTOM_SERVICE, description = "流程节点flowNode、流程编码workflowCode、organization所属组织必填，订单流程flow_type为1")
    public List<String> queryParticipantHttpClient(@Parameter ApprovalFlowStrategyDto dto) {
        List<String> result = new ArrayList<>();
        if (dto == null) {
            throw new BizException("流程审批策略信息必填");
        }
        log.info("流程策略传参ApprovalFlowStrategyDto::{}", JSON.toJSONString(dto));
        List<String> participant = new ArrayList<>();
        //根据业务bizObjectId查询上一节点处理人
        log.info("当前登陆人id::{},当前登陆人姓名::{}", JSON.toJSONString(RequestContext.getCorpLoginId()),RequestContext.getLoginRealName());
        participant.add(RequestContext.getCorpLoginId());
        dto.setParticipant(participant);
        SingleResponse<BOList> singleResponse = BoQueryUtils.Builder(ModelConst.T_APPROVAL_FLOW_STRATEGY)
                .condition()
                .eq("child_flow_node", dto.getFlowNode())
                .eq("workflow_code", dto.getWorkflowCode())
                .eq("flow_type", dto.getFlowType())
                .eq("organization", dto.getOrganization().get(0))
                .End().listBO();
        List<Map<String, Object>> approvalFlowStrategyList = singleResponse.getData().getData();
        if (approvalFlowStrategyList.isEmpty()) {
            throw new BizException("策略为空，请联系管理员添加流程策略");
        }
        log.info("返回流程策略approvalFlowStrategyList::{}", JSON.toJSONString(approvalFlowStrategyList));
        for (Map<String, Object> f : approvalFlowStrategyList) {
            List<SelectorFormat> participants = (List<SelectorFormat>) f.get("participant");
            log.info("上一节点所有participants::{}", JSON.toJSONString(participants));
            log.info("上一节点participant::{}", JSON.toJSONString(dto.getParticipant()));
            List<String> participantsStr = participants.stream().map(SelectorFormat::getId).collect(Collectors.toList());
            log.info("上一节点所有participantsStr::{}", JSON.toJSONString(participantsStr));
            if (participantsStr.contains(dto.getParticipant().get(0))) {
                log.info("存在参与者participant");
                List<SelectorFormat> person = (List<SelectorFormat>) f.get("child_node_participant");
                if (CollectionUtils.isNotEmpty(person)) {
                    result.addAll(person.stream().map(SelectorFormat::getId).collect(Collectors.toList()));
                }
            }
        }
        return result;
    }

    @Path("queryParticipant")
    @POST
    @Operation(summary = "流程审批管理-获取节点参与者", tags = CUSTOM_SERVICE, description = "流程节点flowNode、流程编码workflowCode、organization所属组织必填，订单流程flow_type为1")
    public List<String> queryParticipant(@Parameter ApprovalFlowStrategyDto dto) {
        List<String> result = new ArrayList<>();
        if (dto == null) {
            throw new BizException("流程审批策略信息必填");
        }
        log.info("流程策略传参ApprovalFlowStrategyDto::{}", JSON.toJSONString(dto));
        //根据业务bizObjectId查询上一节点处理人
        log.info("当前登陆人id::{},当前登陆人姓名::{}", JSON.toJSONString(RequestContext.getCorpLoginId()),RequestContext.getLoginRealName());
        String url = HttpClients.getUrl(AppConst.ORDER_CENTER, ServiceUrlConst.APPROVAL_FLOWSTRATEGY_URL);
        Map<String, Object> fileParam = Maps.newHashMap();
        fileParam.put("flowType", dto.getFlowType());
        fileParam.put("workflowCode", dto.getWorkflowCode());
        fileParam.put("flowNode", dto.getFlowNode());
//        fileParam.put("bizObjectId", dto.getBizObjectId());
        fileParam.put("originator", dto.getOriginator());
        fileParam.put("organization", dto.getOrganization());
        fileParam.put("loginId", RequestContext.getCorpLoginId());
        String execute = HttpClients.execute(url, fileParam);
        log.info("返回结果::{}", JSON.toJSONString(execute));
        result = JSONArray.parseArray(execute, String.class);
        return result;
    }

    @Path("startWorkflowInstance")
    @POST
    @Operation(summary = "定标流程审批管理-发起流程", tags = CUSTOM_SERVICE, description = "流程节点flowNode、流程编码workflowCode、organization所属组织必填，订单流程flow_type为1")
    public void startWorkflowInstance(@Parameter StartWorkFlowDto dto) {
        List<String> result = new ArrayList<>();
        if (dto == null) {
            throw new BizException("流程开始信息必填！！");
        }
        log.info("发起定标流程tartWorkFlowDto::{}", JSON.toJSONString(dto));
        workflowService.startWorkflowInstance("calibration_approval_flow",dto.getBizObjectId(), dto.getOriginator(),dto.getDepartmentId(),true,"","","");
    }

    @Path("batchSubmitApproval")
    @POST
    @Operation(summary = "定标流程审批管理-批量审批", tags = CUSTOM_SERVICE, description = "批量审批")
    public SingleResponse<HandleWorkItemValidMessageVO>  batchSubmitApproval(@Parameter BatchSubmitDto batchSubmitDto) {
        if (batchSubmitDto == null) {
            throw new BizException("批量审批信息必填！！");
        }
        log.info("定标流程审批管理-批量审批batchSubmitDto::{}", JSON.toJSONString(batchSubmitDto));
        return workflowService.batchSubmit(batchSubmitDto.getUserId(),batchSubmitDto.getWorkItemIds(), batchSubmitDto.getContent(),batchSubmitDto.getResources());
    }

    @Path("batchDeleteWorkflowInstance")
    @POST
    @Operation(summary = "定标流程-批量删除流程", tags = CUSTOM_SERVICE, description = "批量删除流程")
    public void  batchDeleteWorkflowInstance(@Parameter List<String> bizObjectIds) {
        if (CollectionUtils.isEmpty(bizObjectIds)) {
            throw new BizException("bizObjectIds信息必填！！");
        }
        log.info("定标流程批量删除-批量bizObjectIds信息::{}", JSON.toJSONString(bizObjectIds));
        StringBuffer sql = new StringBuffer("SELECT * \n" +
                "        from commoditymaterials.biz_workflow_instance\n" +
                "        where 1 = 1");
        Map<String, Object> parameter = new HashMap<>();
        sql.append(" and (bizObjectId in (:bizObjectIds))");
        parameter.put("bizObjectIds", bizObjectIds);
//        parameter.put("bizObjectIds", Optional.ofNullable(bizObjectIds.stream().map(e->"\'" + e + "\'").collect(Collectors.joining(","))).orElse(""));
        List<Map<String, Object>> resultList = jdbcTemplate.queryForList(sql.toString(), parameter);
        List<String> instanceIds = resultList.stream().map(e->e.get("id").toString()).collect(Collectors.toList());
        for (String instanceId:instanceIds){
            log.info("待删除-删除流程实例::{}", JSON.toJSONString(instanceId));
            workflowService.deleteWorkflowInstance(instanceId,"询价商品关闭，删除流程实例");
        }
    }

}
